﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using myomscl.DataObjects;
using myomscl.Utils;
using myomscl.Interfaces;

namespace myomscl.Presenters
{
    public class DetailsViewPresenter : ActionPresenter
    {
        #region members

        private readonly AlertViewDAL model;
        private readonly IDetailsView view;

        #endregion

        #region constructor
        public DetailsViewPresenter(IDetailsView _view)
            : this(_view, null)
        { }

        public DetailsViewPresenter(IDetailsView _view, ISessionProvider session)
            : base(_view, session)
        {
            view = base.GetView<IDetailsView>();
            view.OnDetailsLoad += view_OnPageLoad;
            view.OnChangeStatus += view_OnChangeStatus;
            view.OnGereedMelden += view_OnGereedMelden;
            view.OnClearReviewStatus += view_OnClearReviewStatus;
            view.OnMeldingTerugNaarFacturatie += view_MeldingTerugNaarFacturatie;
            view.OnSaveStatusChanges += view_OnSaveStatusChanges;
            view.OnCheckUitgesteldHerstel += view_OnCheckUitgesteldHerstel;
            model = new AlertViewDAL();
        }

        #endregion

        #region private methods

        private void view_OnPageLoad()
        {
            WorkflowFilterSql filterSql = GetWorkflowFilter();

            EstateDataSet.AlertDetailsDataTable detailsTable = model.GetAlertDetails(filterSql);

            if (detailsTable.Rows.Count == 1)
            {
                EstateDataSet.AlertDetailsRow details = detailsTable[0];

                SetAlertsCurrentStatus(details.currentstatus);

                LoadDetailScreenData(details);

                LoadExecuteScreenData(details);

            }
        }

        private void view_OnChangeStatus(int id, Int32 newStatus, Int32 oldStatus, bool preserve)
        {

            var tempChanges = TempChanges;
            var alert = tempChanges.Where(a => a.id == view.AlertId).FirstOrDefault();
            if (alert != null)
            {
                tempChanges.Remove(alert);
            }
            using (WorkflowEntitySet context = new WorkflowEntitySet())
            {
                alert = context.Alert.Where(a => a.id == view.AlertId).First();
                alert.currentstatus = (int)newStatus;
            }
            tempChanges.Add(alert);
            TempChanges = tempChanges;
            SetAlertsCurrentStatus((int)newStatus);
        }

        private void SetAlertsCurrentStatus(int currentstatus)
        {
            Session["execute_CurrentStatus"] = currentstatus;

            var tempChanges = TempChanges;
            var tempAlert = tempChanges.Where(a => a.id == view.AlertId).FirstOrDefault();
            if (tempAlert != null)
            {
                Session["execute_CurrentStatus"] = tempAlert.currentstatus;
            }
        }

        private void LoadDetailScreenData(EstateDataSet.AlertDetailsRow details)
        {
            if (details != null)
            {
                view.Code = details.code;
                view.Location = details.location;
                view.AlertType = WorkflowEnums.AlertTypeList[details.alerttype];
                view.ActivityType = WorkflowEnums.ActivityTypeList[details.activitytype];

                view.ContractorName = details.contractorname;
                view.EstimateStartDate = details.estimatestartdate.ToShortDateString();
                view.EstimateEndDate = details.estimateenddate.ToShortDateString();
                view.CreationDate = details.creationdate.ToShortDateString();
                view.Area = details.estimatearea.ToString();
                view.Traffic = details.trafficproblems;
                view.UseMunicipContractor = (details.usemunicipconstractor) ? WorkflowEnums.ConstuctorChoise[1]
                    : WorkflowEnums.ConstuctorChoise[0];


                using (WorkflowEntitySet context = new WorkflowEntitySet())
                {
                    var alert = context.Alert.Where(a => a.id == view.AlertId).First();
                    if (CurrentUser.Type == WorkflowEnums.UserType.NetworkOperator)
                    {
                        view.NetworkOperatorName = alert.municipalityname;
                    }
                    else
                    {
                        view.NetworkOperatorName = alert.networkoperatorname;
                    }
                }
            }
        }

        private void LoadExecuteScreenData(EstateDataSet.AlertDetailsRow details)
        {
            if (details != null)
            {
                AlertDetails alert = new AlertDetails()
                {
                    CurrentStatus = (WorkflowEnums.Status)Int32.Parse(Session["execute_CurrentStatus"].ToString()),
                    UseMunicipConstractor = (details.usemunicipconstractor) ? 1 : 0,
                    MunicipalityId = details.municipalityid,
                    //Comments = details.comments,
                    ContractorId = string.IsNullOrEmpty(details.contractorid) ? null : (Nullable<int>)Int32.Parse(details.contractorid),
                    ActivityType = details.activitytype
                };

                if (!string.IsNullOrEmpty(view.Area))
                    alert.EstimateArea = Int32.Parse(view.Area);
                if (!string.IsNullOrEmpty(view.EstimateStartDate))
                    alert.EstimateStartDate = DateTime.Parse(view.EstimateStartDate);
                if (!string.IsNullOrEmpty(view.EstimateEndDate))
                    alert.EstimateEndDate = DateTime.Parse(view.EstimateEndDate);

                Session[WorkflowConstants.ExecuteData] = alert;

            }
        }

        private void view_OnGereedMelden()
        {
            using (WorkflowEntitySet context = new WorkflowEntitySet())
            {
                var alert = context.Alert.Where(a => a.id == view.AlertId).First();

                alert.actualstartdate = alert.estimatestartdate;
                alert.actualenddate = alert.estimateenddate;
                alert.actualarea = alert.estimatearea;
                alert.currentstatus = (int)WorkflowEnums.Status.Executed4Municipality;

                var alertHistory = new AlertHistory()
                {
                    Alert = alert,
                    date = DateTime.Now,
                    Person = context.Person.Where(p => p.id == CurrentUser.Id).First(),
                    status = (int)WorkflowEnums.Status.Executed4Municipality
                };

                context.AddToAlertHistory(alertHistory);

                context.SaveChanges();
            }
        }

        private void view_OnClearReviewStatus()
        {
            var tempChanges = TempChanges;
            var tempAlert = tempChanges.Where(a => a.id == view.AlertId).FirstOrDefault();
            if (tempAlert != null)
            {
                tempChanges.Remove(tempAlert);
                TempChanges = tempChanges;

                if (Session["TempAlertMaterials"] != null)
                {
                    var tempAlertMaterials = Session["TempAlertMaterials"] as List<AlertMaterials>;
                    var usedAlertMaterials = tempAlertMaterials.Where(am => am.Alert.id == view.AlertId).ToList();
                    if (usedAlertMaterials.Any())
                    {
                        tempAlertMaterials = tempAlertMaterials.Except(usedAlertMaterials).ToList();
                        Session["TempAlertMaterials"] = tempAlertMaterials;
                    }
                }

            }
        }

        private void view_MeldingTerugNaarFacturatie()
        {
            using (WorkflowEntitySet context = new WorkflowEntitySet())
            {
                var alert = context.Alert.Where(a => a.id == view.AlertId).First();
                alert.archived = false;
                context.SaveChanges();
            }
        }

        private void view_OnSaveStatusChanges()
        {

            var tempChanges = TempChanges;
            var tempAlert = tempChanges.Where(a => a.id == view.AlertId).FirstOrDefault();
            if (tempAlert != null)
            {
                WorkflowFilter filter = new WorkflowFilter()
                {
                    AlertId = tempAlert.id
                };
                WorkflowFilterSql filterSql = new WorkflowFilterSql(filter);

                MainListDAL mainListDal = new MainListDAL();
                var contacts = mainListDal.GetContactAlerts(filterSql);
                SavePresenter saveHelper = new SavePresenter(null, Session);

                using (WorkflowEntitySet context = new WorkflowEntitySet())
                {

                    switch ((WorkflowEnums.Status)tempAlert.currentstatus)
                    {
                        case WorkflowEnums.Status.Approved:
                        case WorkflowEnums.Status.PartiallyApproved:
                        case WorkflowEnums.Status.Rejected:
                            {
                                saveHelper.SaveNewAlert(tempAlert, context);
                            }
                            break;

                        case WorkflowEnums.Status.Accepted:
                        case WorkflowEnums.Status.AcceptedPartially:
                        case WorkflowEnums.Status.Declined:
                            {
                                saveHelper.SaveExecutedAlert(tempAlert, context);
                            }
                            break;
                    }
                    var contact = contacts.FindByid(tempAlert.id);
                    SendNotification(contact, tempAlert.currentstatus, tempAlert.id.ToString());

                    context.SaveChanges();
                    tempChanges.Remove(tempAlert);
                    TempChanges = tempChanges;
                }
            }

        }

        private WorkflowFilterSql GetWorkflowFilter()
        {
            WorkflowFilter filter = new WorkflowFilter
            {
                AlertId = view.AlertId
            };

            return new WorkflowFilterSql(filter);
        }

        private void SendNotification(EstateDataSet.ContactAlertsRow contact, int status, string alertid)
        {
            if (CurrentUser.Type == WorkflowEnums.UserType.Municipality)
            {
                if ((WorkflowEnums.Status)status == WorkflowEnums.Status.Accepted || (WorkflowEnums.Status)status == WorkflowEnums.Status.AcceptedPartially)
                {
                    //save invoice data
                    WorkflowFilter filter = new WorkflowFilter()
                    {
                        AlertId = Int32.Parse(alertid)
                    };
                    AlertViewDAL dal = new AlertViewDAL();
                    dal.PrepareInvoiceData(new WorkflowFilterSql(filter));
                }

                if (contact != null && contact.nonotification)
                    Notification.SendNotification(alertid, status, contact);
            }
            else
            {
                if (contact != null &&
                    contact.munnotification &&
                    status != (Int32)WorkflowEnums.Status.Deleted &&
                    status != (Int32)WorkflowEnums.Status.Sent)
                    Notification.SendNotification(alertid, status, contact);
            }
        }

        private bool view_OnCheckUitgesteldHerstel()
        {
            bool result = true;
            using (WorkflowEntitySet context = new WorkflowEntitySet())
            {
                var tempChanges = TempChanges;
                var alert = tempChanges.Where(a => a.id == view.AlertId).FirstOrDefault();
                if (alert == null)
                {
                    alert = context.Alert.Include("AlertMaterials").Where(a => a.id == view.AlertId).First();
                }
                if (alert.AlertMaterials != null && alert.AlertMaterials.Any())
                {
                    result = !alert.AlertMaterials.Where(am => am.uitstel == true).Any();
                }
            }
            return result;
        }
        #endregion
    }
}
